﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace NetBay.Core.Encryption
{
    public class AesEncryption
    {
        private const string PASSWORD = "]__/!P@S5w0r]F0R4tRoN1[!_";
        private const string SALT = "s@1tV4lu3!";

        /// <summary>
        /// Encrypts the specified input.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <returns></returns>
        public static string Encrypt(string input)
        {
            // Test data
            string data = input;
            byte[] utfdata = UTF8Encoding.UTF8.GetBytes(data);
            byte[] saltBytes = UTF8Encoding.UTF8.GetBytes(SALT);

            // Our symmetric encryption algorithm
            using (AesManaged aes = new AesManaged())
            {

                // We're using the PBKDF2 standard for password-based key generation
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(PASSWORD, saltBytes);

                // Setting our parameters
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;

                aes.Key = rfc.GetBytes(aes.KeySize/8);
                aes.IV = rfc.GetBytes(aes.BlockSize/8);

                // Encryption
                ICryptoTransform encryptTransf = aes.CreateEncryptor();

                // Output stream, can be also a FileStream
                MemoryStream encryptStream = new MemoryStream();
                CryptoStream encryptor = new CryptoStream(encryptStream, encryptTransf, CryptoStreamMode.Write);

                encryptor.Write(utfdata, 0, utfdata.Length);
                encryptor.Flush();
                encryptor.Close();

                // Showing our encrypted content
                byte[] encryptBytes = encryptStream.ToArray();
                //string encryptedString = UTF8Encoding.UTF8.GetString(encryptBytes, 0, encryptBytes.Length);
                string encryptedString = Convert.ToBase64String(encryptBytes);

                return encryptedString;
            }
        }

        /// <summary>
        /// Decrypts the specified base64 input.
        /// </summary>
        /// <param name="base64Input">The base64 input.</param>
        /// <returns></returns>
        public static string Decrypt(string base64Input)
        {

            //byte[] encryptBytes = UTF8Encoding.UTF8.GetBytes(input);
            byte[] encryptBytes = Convert.FromBase64String(base64Input);
            byte[] saltBytes = Encoding.UTF8.GetBytes(SALT);

            // Our symmetric encryption algorithm
            using (AesManaged aes = new AesManaged())
            {
                // We're using the PBKDF2 standard for password-based key generation
                Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(PASSWORD, saltBytes);

                // Setting our parameters
                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
                aes.KeySize = aes.LegalKeySizes[0].MaxSize;

                aes.Key = rfc.GetBytes(aes.KeySize/8);
                aes.IV = rfc.GetBytes(aes.BlockSize/8);

                // Now, decryption
                ICryptoTransform decryptTrans = aes.CreateDecryptor();

                // Output stream, can be also a FileStream
                MemoryStream decryptStream = new MemoryStream();
                CryptoStream decryptor = new CryptoStream(decryptStream, decryptTrans, CryptoStreamMode.Write);

                decryptor.Write(encryptBytes, 0, encryptBytes.Length);
                decryptor.Flush();
                decryptor.Close();

                // Showing our decrypted content
                byte[] decryptBytes = decryptStream.ToArray();
                string decryptedString = UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length);

                return decryptedString;
            }
        }
    }
}
